package plg_search_sqlitefts

import (
	. "github.com/mickael-kerjean/filestash/server/common"
	"time"
)

var (
	SEARCH_ENABLE      func() bool
	SEARCH_PROCESS_MAX func() int
	SEARCH_PROCESS_PAR func() int
	SEARCH_REINDEX     func() int
	CYCLE_TIME         func() int
	INDEXING_EXT       func() string
	MAX_INDEXING_FSIZE func() int
	INDEXING_EXCLUSION = []string{
		"/node_modules/", "/bower_components/",
		"/.cache/", "/.npm/", "/.git/",
	}
)

func init() {
	SEARCH_ENABLE = func() bool {
		return Config.Get("features.search.enable").Schema(func(f *FormElement) *FormElement {
			if f == nil {
				f = &FormElement{}
			}
			f.Name = "enable"
			f.Type = "enable"
			f.Target = []string{
				"process_max", "process_par", "reindex_time",
				"cycle_time", "max_size", "indexer_ext",
			}
			f.Description = "Enable/Disable full text search"
			f.Placeholder = "Default: false"
			f.Default = false
			return f
		}).Bool()
	}
	SEARCH_PROCESS_MAX = func() int {
		return Config.Get("features.search.process_max").Schema(func(f *FormElement) *FormElement {
			if f == nil {
				f = &FormElement{}
			}
			f.Id = "process_max"
			f.Name = "process_max"
			f.Type = "number"
			f.Description = "Size of the pool containing the indexers"
			f.Placeholder = "Default: 5"
			f.Default = 5
			return f
		}).Int()
	}
	SEARCH_PROCESS_PAR = func() int {
		return Config.Get("features.search.process_par").Schema(func(f *FormElement) *FormElement {
			if f == nil {
				f = &FormElement{}
			}
			f.Id = "process_par"
			f.Name = "process_par"
			f.Type = "number"
			f.Description = "How many concurrent indexers are running in the same time (requires a restart)"
			f.Placeholder = "Default: 2"
			f.Default = 2
			return f
		}).Int()
	}
	SEARCH_REINDEX = func() int {
		return Config.Get("features.search.reindex_time").Schema(func(f *FormElement) *FormElement {
			if f == nil {
				f = &FormElement{}
			}
			f.Id = "reindex_time"
			f.Name = "reindex_time"
			f.Type = "number"
			f.Description = "Time in hours after which we consider our index to be stale and needs to be reindexed"
			f.Placeholder = "Default: 24h"
			f.Default = 24
			return f
		}).Int()
	}
	CYCLE_TIME = func() int {
		return Config.Get("features.search.cycle_time").Schema(func(f *FormElement) *FormElement {
			if f == nil {
				f = &FormElement{}
			}
			f.Id = "cycle_time"
			f.Name = "cycle_time"
			f.Type = "number"
			f.Description = "Time the indexer needs to spend for each cycle in seconds (discovery, indexing and maintenance)"
			f.Placeholder = "Default: 10s"
			f.Default = 10
			return f
		}).Int()
	}
	MAX_INDEXING_FSIZE = func() int {
		return Config.Get("features.search.max_size").Schema(func(f *FormElement) *FormElement {
			if f == nil {
				f = &FormElement{}
			}
			f.Id = "max_size"
			f.Name = "max_size"
			f.Type = "number"
			f.Description = "Maximum size of files the indexer will perform full text search"
			f.Placeholder = "Default: 524288000 => 512MB"
			f.Default = 524288000
			return f
		}).Int()
	}
	INDEXING_EXT = func() string {
		return Config.Get("features.search.indexer_ext").Schema(func(f *FormElement) *FormElement {
			if f == nil {
				f = &FormElement{}
			}
			f.Id = "indexer_ext"
			f.Name = "indexer_ext"
			f.Type = "text"
			f.Description = "File extension we want to see indexed"
			f.Placeholder = "Default: org,txt,docx,pdf,md,form"
			f.Default = "org,txt,docx,pdf,md,form"
			return f
		}).String()
	}

	Hooks.Register.Onload(func() {
		SEARCH_ENABLE()
		SEARCH_PROCESS_MAX()
		SEARCH_PROCESS_PAR()
		SEARCH_REINDEX()
		CYCLE_TIME()
		MAX_INDEXING_FSIZE()
		INDEXING_EXT()

		onChange := Config.ListenForChange()
		runner := func() {
			startSearch := false
			for {
				if SEARCH_ENABLE() == false {
					select {
					case <-onChange.Listener:
						startSearch = SEARCH_ENABLE()
					}
					if startSearch == false {
						continue
					}
				}
				sidx := SProc.Peek()
				if sidx == nil {
					time.Sleep(5 * time.Second)
					continue
				}
				sidx.mu.Lock()
				sidx.Execute()
				sidx.mu.Unlock()
			}
		}
		for i := 0; i < SEARCH_PROCESS_PAR(); i++ {
			go runner()
		}
	})
}
